package com.nervenets.web.controller.user;

import com.nervenets.utils.GeoUtil;
import com.nervenets.web.controller.BaseController;
import com.nervenets.web.controller.IdTokenParams;
import com.nervenets.web.controller.TokenParams;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.entity.ResponseResult;
import com.nervenets.web.hibernate.dao.AddressDao;
import com.nervenets.web.hibernate.dao.UserDao;
import com.nervenets.web.hibernate.domain.Address;
import com.nervenets.web.hibernate.domain.user.User;
import com.nervenets.web.redis.domain.user.UserStored;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.Optional;
import java.util.Set;

@Api(value = "地址接口v1", description = "地址相关接口")
@RestController
@RequestMapping("/api/v1/address")
public class AddressController extends BaseController {
    @Resource
    private AddressDao addressDao;
    @Resource
    private UserDao userDao;

    @ApiOperation("用户地址列表")
    @PostMapping("/list")
    public ResponseResult list(@RequestBody TokenParams params) {
        final Set<ConstraintViolation<TokenParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        final long userId = params.resolveUserId();
        if (0 == userId) return errorMessage(MessageCode.code_777);
        final Optional<User> user = userDao.findById(userId);
        if (!user.isPresent()) return errorMessage(MessageCode.code_777);

        return successMessage(addressDao.findAllByUserIdOrderByDefDesc(userId));
    }

    @ApiOperation("用户地址详情")
    @PostMapping("/detail")
    public ResponseResult detail(@RequestBody IdTokenParams params) {
        final Set<ConstraintViolation<IdTokenParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        final long userId = params.resolveUserId();
        if (0 == userId) return errorMessage(MessageCode.code_777);
        final UserStored user = globalService.getUser(userId);
        if (null == user) return errorMessage(MessageCode.code_777);

        final Optional<Address> address = addressDao.findById(params.getTargetId());
        return address.isPresent() ? successMessage(address) : errorMessage(MessageCode.code_404, "地址不存在");
    }

    @ApiOperation("用户地址编辑")
    @PostMapping("/edit")
    public ResponseResult edit(@RequestBody AddressEditParams params) {
        final Set<ConstraintViolation<AddressEditParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }
        final long userId = params.resolveUserId();
        if (0 == userId) return errorMessage(MessageCode.code_777);
        final Optional<User> user = userDao.findById(userId);
        if (!user.isPresent()) return errorMessage(MessageCode.code_777);

        if (!GeoUtil.isValidChinaCoordinate(params.getLongitude(), params.getLatitude())) {
            return errorMessage(MessageCode.code_444, "地址的经纬度错误！");
        }

        Address address = new Address();
        if (params.getAddressId() > 0) {
            address = addressDao.findById(params.getAddressId()).orElse(null);
            if (null == address) return errorMessage(MessageCode.code_404, "您编辑的地址不存在");
        }

        address.setUserId(userId);
        address.setName(params.getName());
        address.setGender(params.getGender());
        address.setMobile(params.getMobile());
        address.setAreaId(params.getAreaId());
        address.setDetail(params.getDetail());
        address.setDef(params.isDef());
        address.setLongitude(params.getLongitude());
        address.setLatitude(params.getLatitude());
        addressDao.save(address);

        if (params.isDef()) {
            addressDao.updateAllAddressDefToFalse(userId);
            addressDao.updateAddressDefStatus(true, address.getId());
        }

        return successMessage(address);
    }

    @ApiOperation("用户地址设置为默认")
    @PostMapping("/def")
    public ResponseResult def(@RequestBody IdTokenParams params) {
        final Set<ConstraintViolation<IdTokenParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }
        final long userId = params.resolveUserId();
        if (0 == userId) return errorMessage(MessageCode.code_777);
        final Optional<User> user = userDao.findById(userId);
        if (!user.isPresent()) return errorMessage(MessageCode.code_777);

        addressDao.updateAllAddressDefToFalse(userId);
        addressDao.updateAddressDefStatus(true, params.getTargetId());
        return successMessage();
    }

    @ApiOperation("用户地址删除")
    @PostMapping("/delete")
    public ResponseResult delete(@RequestBody IdTokenParams params) {
        final Set<ConstraintViolation<IdTokenParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }
        final long userId = params.resolveUserId();
        if (0 == userId) return errorMessage(MessageCode.code_777);
        final Optional<User> user = userDao.findById(userId);
        if (!user.isPresent()) return errorMessage(MessageCode.code_777);

        final Address address = addressDao.findById(params.getTargetId()).orElse(null);
        if (null == address) return errorMessage(MessageCode.code_404, "您删除的地址不存在");

        addressDao.delete(address);

        return successMessage();
    }
}
